package com.phrp.controller;

import com.phrp.dao.UserDao;
import com.phrp.entity.User;
import com.phrp.exception.CustomizationException;
import com.phrp.service.UserService;
import com.phrp.util.jwt.JwtUtil;
import com.phrp.util.returnResult.ResponseResult;
import com.phrp.util.returnResult.ReturnInfoEnum;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.LinkedHashMap;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author ssc
 * @since 2024-05-05
 */
@RestController
@RequestMapping("/api/user")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private UserDao userDao;

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    /**
     * 用户登录
     *
     * @param loginData
     * @return
     */
    @PostMapping(value = "login/password")
    public ResponseResult pwdLogin(@RequestBody HashMap<String, String> loginData) {
        // 由于配置了shiro，所以会对请求进行拦截，所以就不会去service层进行登录验证，直接在controller中进行
        // 将密码加密
        Md5Hash md5Pwd = new Md5Hash(loginData.get("password"), loginData.get("phone"), 1024);

        QueryWrapper<User> query = new QueryWrapper<>();
        query.eq("phone", loginData.get("phone"));

        User user = userDao.selectOne(query);

        if (user == null) {
            // 用户不存在
            return new ResponseResult(ReturnInfoEnum.USERINFO_EMPTY);
        }

        if(!md5Pwd.toHex().equals(user.getPassword())){
            // 密码错误
            return new ResponseResult(ReturnInfoEnum.PASSWORD_ERROR);
        }

        // 得到上一次登录时间
        String logTime = String.valueOf(user.getLastLogTime());

        // 身份验证通过，刷新登录时间
        user.setLastLogTime(LocalDateTime.now());


        // 更新登录时间
        UpdateWrapper<User> update = new UpdateWrapper<>();
        update.eq("u_uuid", user.getUUuid())
                .set("last_log_time", user.getLastLogTime());

        int i = userDao.update(null, update);

        if (i != 1) {
            // 更新失败，数据库错误，抛出异常
            throw new CustomizationException(ReturnInfoEnum.DATA_FAIL);
        }

        // 更新成功
        // 获取token，并将其返回给前端
        String token = jwtUtil.generateToken(user.getPhone());

        HashMap<String, String> map = new LinkedHashMap<>();
        map.put("token", token);
        map.put("logTime", logTime);
        return new ResponseResult<HashMap>(ReturnInfoEnum.SUCCESS, map);
    }

    /**
     * 验证码登录
     * @param map
     * @return
     */
    @PostMapping(value = "login/code")
    public ResponseResult codeLogin(@RequestBody HashMap<String,String> map){
        // 获取用户数据
        int i = userDao.selectByPhone(map.get("phone"));
        if(i != 1){
            return ResponseResult.error("2001","用户不存在，请注册！");
        }
        String code = redisTemplate.opsForValue().get(map.get("phone"));
        if(!code.equals(map.get("code"))){
            return ResponseResult.error("2002","验证码错误！");
        }
        // 获取token，并将其返回给前端
        String token = jwtUtil.generateToken(map.get("phone"));

        HashMap<String, String> hashMap = new LinkedHashMap<>();
        map.put("token", token);
        return new ResponseResult(ReturnInfoEnum.SUCCESS,hashMap);
    }

    /**
     * 获取验证码
     * @param phone
     * @return
     */
    @GetMapping(value = "getCode")
    public ResponseResult getCode(@RequestParam String phone){
        return userService.getCode(phone);
    }

    /**
     * 注册
     * @param map
     * @return
     */
    @PostMapping(value = "register")
    public ResponseResult register(@RequestBody HashMap<String,String> map){
        return userService.register(map);
    }

}
